package parser

import (
	"fmt"
	"sql2entity/util"
	"strings"
)

// keys MySQL中类型关键词
var keys = []string{
	// 整数类型
	"tinyint",
	"smallint",
	"mediumint",
	"integer",
	"bigint",
	"int",
	// 小数类型
	"float",
	"double",
	"decimal",
	// 时间类型
	"datetime",
	"date",
	"time",
	"year",
	"timestamp",
	// 文本类型
	"varchar",
	"char",
	"tinyblob",
	"tinytext",
	"mediumblob",
	"mediumtext",
	"longblob",
	"longtext",
	"blob",
	"text",
}

// TableInfo数据表信息
type TableInfo struct {
	TableName   string
	TableFields []*TableField
}

// TableField 数据表字段信息
type TableField struct {
	FieldName    string
	FieldType    string
	FieldLength  int
	FieldComment string
}

// SplitLengthAfter 分割出SQL语句中类型后面的长度信息，如果没有就设置为-1
func SplitLengthAfter(text string) int {
	if text[0] != '(' {
		return -1
	}
	r := 0
	for i := 0; text[i] != ')'; i++ {
		r = r*10 + (int(text[i] - '0'))
	}
	return r
}

// SplitWordBefore 分割出index之后的一个单词，并去掉反引号
func SplitWordBefore(content string, index int) string {
	if index < 0 {
		return ""
	}
	for content[index] == ' ' || content[index] == '`' {
		index--
	}
	bu := strings.Builder{}
	for content[index] != ' ' && content[index] != '`' {
		bu.WriteByte(content[index])
		index--
	}
	return util.ReverseString(bu.String())
}

// FindCommentAfter 找到该属性对应的注释
func FindCommentAfter(text string) string {
	const COMMENT = "comment"
	dotIndex := strings.Index(text, ",")
	commentIndex := strings.Index(text, COMMENT)
	if commentIndex == -1 || commentIndex >= dotIndex {
		return ""
	}
	text = text[commentIndex+len(COMMENT):]
	bu := strings.Builder{}
	i := 0
	for i < dotIndex && (text[i] == ' ' || text[i] == '\'') {
		i++
	}
	for i < dotIndex && text[i] != ' ' && text[i] != '\'' {
		bu.WriteByte(text[i])
		i++
	}
	return bu.String()
}

// GetTableInfoFromSql 从SQL语句中获取数据表信息
func GetTableInfoFromSql(sql string) *TableInfo {
	sql = strings.ToLower(sql)
	left := strings.Index(sql, "(")
	tableName := SplitWordBefore(sql, left-1)
	fields := []*TableField{}
	for _, key := range keys {
		index := FindKeyIndex(sql, key)
		for index != -1 {
			fmt.Println(index, key)
			fields = append(fields, &TableField{
				FieldName:    SplitWordBefore(sql, index-1),
				FieldType:    key,
				FieldLength:  SplitLengthAfter(sql[index+len(key):]),
				FieldComment: FindCommentAfter(sql[index:]),
			})
			sql = strings.Replace(sql, key, util.GenerateString("*", len(key)), 1)
			index = FindKeyIndex(sql, key)
		}
	}
	return &TableInfo{
		TableName:   tableName,
		TableFields: fields,
	}
}

// FindKeyIndex 找到SQL语句中类型关键词的位置，没有就返回-1
func FindKeyIndex(sql, key string) int {
	index := strings.Index(sql, key)
	if index == -1 || index == 0 {
		return -1
	}
	// 类型关键词左边应该是一个空格，右边应该是左括号或者空格
	if sql[index-1] == ' ' && (sql[index+len(key)] == ' ' || sql[index+len(key)] == '(') {
		return index
	}
	fill := util.GenerateString("*", len(key))
	sql = strings.Replace(sql, key, fill, 1)
	return FindKeyIndex(sql, key)
}
